跳到主要内容

Java Netty 提供的几种传输包

Netty 提供的传输包

Netty 内置了一些可开箱即用的传输包。因为并不是它们所有的传输都支持每一种协议,所以你必须选择一个和你的应用程序所使用的协议相容的传输工具。

其中 OIO 已经不再支持了,就不介绍了

接下来就讨论这些传输包

NIO 非阻塞 IO

NIO 提供了一个所有 I/O 操作的全异步的实现。它主要使用自 NIO 子系统被引入 JDK 1. 4 时便可用的基于选择器的API。

选择器背后的基本概念是充当一个注册表,在那里你将可以请求在 Channel 的状态发生变化时得到通知。可能的状态变化有:

  • 新的 Channel 已被接受并且就绪;
  • Channel 连接已经完成;
  • Channel 有已经就绪的可供读取的数据;
  • Channel 可用于写数据。

选择器运行在一个检查状态变化并对其做出相应响应的线程上,在应用程序对状态的改变做出响应之后,选择器将会被重置,并将重复这个过程。

但是 Netty 这个框架内部屏蔽了这些细节,如下图所示:

Epoll 用于 Linux 的本地非阻塞传输

Netty 的 NIO 传输基于 Java 提供的异步/非阻塞网络编程的通用抽象。虽然这保证了 Netty 的非阻塞 API 可以在任何平台上使用,但它也包含了相应的限制,因为 JDK 为了在所有系统上提供相同的功能,必须做出妥协。

Linux 作为高性能网络编程的平台,其重要性与日俱增,这催生了大量先进特性的开发,其中包括 epoll (IO 多路复用)一个高度可扩展的 I/O 事件通知特性。

这个 API 自 Linux 内核版本 2.5.44 (2002) 被引入,提供了比旧的 POSIX select 和 poll 系统调用有更好的性能,同时现在也是 Linux 上非阻塞网络编程的事实标准。

实际上 Linux JDK NIO API 使用了这些 epoll 调用。

Netty 为 Linux 提供了一组 NIO API, 其以一种和它本身的设计更加一致的方式使用 epoll,并且以一种更加轻量的方式使用中断。高负载下它的性能要优于 JDK 的 NIO 实现。

这个传输的语义与上图所示的完全相同,而且它的用法也是简单直接的。如果要在那个代码清单中使用 epoll 替代 NIO,只需要将 NioEventLoopGroup 替换为 EpollEventLoopGroup,并且将 NioServerSocketChannel.class 替换为 EpollServerSocketChannel.class 即可。

用于 JVM 内部通信的 Local 传输

Netty 提供了一个 Local 传输,用于在同一个 JVM 中运行的客户端和服务器程序之间的异步通信。同样,这个传输也支持对于所有 Netty 传输实现都共同的 API。

在这个传输中,和服务器 Channel 相关联的 SocketAddress 并没有绑定物理网络地址;相反,只要服务器还在运行,它就会被存储在注册表里,并在 Channel 关闭时注销。因为这个传输并不接受真正的网络流量,所以它并不能够和其他传输实现进行互操作。

因此,客户端希望连接到(在同一个 JVM 中)使用了这个传输的服务器端时也必须使用它。除了这个限制,它的使用方式和其他的传输一模一样。

Embedded 传输

Netty 提供了一种额外的传输,使得你可以将一组 ChannelHandler 作为帮助器类嵌入到其他的 ChannelHandler 内部。通过这种方式,你将可以扩展一个 ChannelHandler 的功能,而又不需要修改其内部代码。

各种传输的应用场景